package com.schoolai.schoolset.controller;

import com.schoolai.entity.SchoolAiDietaryRequirements;
import com.schoolai.entity.SchoolSetAfterSchoolService;
import com.schoolai.schoolset.req.SetAfterSchoolServiceREQ;
import com.schoolai.schoolset.service.ISchoolSetAfterSchoolServiceService;
import com.schoolai.util.base.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author bobby
 * @since 2025-11-06
 */
@RestController
@RequestMapping("/SchoolSetAfterSchoolService")
@Slf4j
@Tag(name = "课后服务", description = "课后服务相关操作")

public class AfterSchoolServiceController {
    @Resource
    private RedissonClient redissonClient;

    @Autowired
    ISchoolSetAfterSchoolServiceService schoolSetAfterSchoolServiceService;
    @Operation(summary = "查询课后服务")
    @PostMapping("/search")
    @ApiResponses({
            @ApiResponse(responseCode = "20000", description = "操作成功"),
            @ApiResponse(responseCode = "999", description = "错误")
    })
    Result search(@RequestBody SetAfterSchoolServiceREQ req){
        return schoolSetAfterSchoolServiceService.queryPage(req);
    }
    @Operation(summary = "课后服务报名")
    @PostMapping("/signUpAfterSchoolService")
    @ApiResponses({
            @ApiResponse(responseCode = "20000", description = "操作成功"),
            @ApiResponse(responseCode = "999", description = "错误")
    })
    Result signUpAfterSchoolService(@Parameter(description = "课后服务ID", required = true, example = "1")  String afterSchoolServiceId,
                                    @Parameter(description = "学生ID", required = true, example = "1")  String stuId){
        stuId = UUID.randomUUID().toString();
        afterSchoolServiceId = "1";
        Result result =  new Result();
        // 加一个分布式锁
        RLock rLock = redissonClient.getFairLock("afterSchoolService"+afterSchoolServiceId);
        boolean isLocked = false;
        try {
            // 不加时间分布式锁会立即失败（加锁失败）。即使当时有库存由于其他线程在使用并加锁，这样会导致业务流程不被执行
            isLocked = rLock.tryLock(100, 10, TimeUnit.SECONDS);
            if(isLocked){
                result = schoolSetAfterSchoolServiceService.signUpAfterSchoolService(afterSchoolServiceId,stuId);
            }
        }catch (Exception e){
            log.error(e.getMessage());
        }finally {
            if(isLocked){//加锁成功还用解锁，也可以用redisson自己的看门狗解锁，但要等到30S的周期，效率不高
                rLock.unlock();
            }
        }
        return result;
    }
    @Operation(summary = "通过id课后服务信息")
    @GetMapping("/{id}")
    public Result view(@PathVariable("id") String id) {
        return Result.ok(schoolSetAfterSchoolServiceService.getById(id));
    }

    @Operation(summary = "新增课后服务信息")
    @PostMapping
    public Result save(@RequestBody SchoolSetAfterSchoolService schoolSetAfterSchoolService){
        return Result.ok(schoolSetAfterSchoolServiceService.saveOrUpdate(schoolSetAfterSchoolService));
    }
    @Operation(summary = "修改课后服务信息")
    @PutMapping
    Result update(@RequestBody SchoolSetAfterSchoolService schoolSetAfterSchoolService){
        schoolSetAfterSchoolService.setUpdatedTime(new Date());
        return Result.ok(schoolSetAfterSchoolServiceService.updateById(schoolSetAfterSchoolService));
    }
    @Operation(summary = "删除课后服务信息")
    @DeleteMapping("/{id}")
    Result delete(@PathVariable("id") String id){
        SchoolSetAfterSchoolService schoolSetAfterSchoolService = schoolSetAfterSchoolServiceService.getById(id);
        if(schoolSetAfterSchoolService == null) {
            return Result.error("操作失败！删除信息不存在！");
        }
        schoolSetAfterSchoolService.setDeletedTime(new Date());
        schoolSetAfterSchoolService.setUpdatedTime(new Date());
        return Result.ok(schoolSetAfterSchoolServiceService.updateById(schoolSetAfterSchoolService));
    }
}
